package dd.prog2.exercises.set10;

import java.util.Iterator;

public class MyDeque<T> implements Iterable<T> {

	private int capacity;
	private int size = 0;
	public T[] ring;
	private int first = 0;
	private int last = 0;

	public MyDeque(int i) {
		this.capacity = i;
		this.ring = (T[]) new Object[i];
	}

	boolean isEmpty() {
		if (this.size == 0)
			return true;
		return false;
	}

	boolean isFull() {
		if (this.size == this.capacity)
			return true;
		return false;
	}

	// liefert die Anzahl der aktuell enthaltenen Elemente.
	int size() {
		return this.size;
	}

	int capacity() {
		return this.capacity;
	}

	// get(0) liefert immer das erste Element,
	// unabhängig davon, wo genau es im Array abgelegt ist!
	T get(int i) {
		return null;
	}

	// fügt vor dem ersten Element ein und macht das neue zum ersten Element.
	void addFirst(T e) {
		if (!this.isFull()) {
			if (isEmpty()) {
				last = first;
			} else
				first--;
			if (first < 0) {
				first = capacity - 1;
			}
			ring[first] = e;
			size++;
		}
	}

	T getFirst() {
		return ring[first];
	}

	T removeFirst() {
		T tmp = ring[first];
		ring[first] = null;
		size--;
		first++;
		if (first == capacity) {
			first = 0;
		}
		return tmp;
	}

	// fügt nach dem letzten Element ein und macht das neue zum letzten Element.
	void addLast(T e) {
		if (!this.isFull()) {
			if (isEmpty()) {
				first = last;
			} else {
				last++;
			}
			if ((last) == capacity)
				last = 0;
			ring[last] = e;
			size++;
		} else
			System.err.println("FULL!!!");
	}

	T getLast() {
		return ring[last];
	}

	T removeLast() {
		T tmp = ring[last];
		ring[last] = null;
		last--;
		size--;
		if (last < 0) {
			last = capacity - 1;
		}
		return tmp;
	}

	// erzeugt eine String-Repräsentation des aktuellen Zustands.
	public String toString() {
		String res = "[ ";
		Iterator<T> it = iterator();
		while (it.hasNext()) {
			res += it.next() + " ";
		}
		res += "]";
		return res;
	}

	public Iterator<T> iterator() {
		return new MyIterator();
	}

	private class MyIterator implements Iterator<T> {
		private int curr;

		private MyIterator() {
			curr = first;
		}

		public boolean hasNext() {
			if (isEmpty())
				return false;
			if (curr == last + 1)
				return false;
			if (curr == capacity)
				curr = 0;
			return true;
		}

		public T next() {
			return ring[curr++];
		}

		public void remove() {
			throw new UnsupportedOperationException();
		}
	}

}
